package golang

import (
	"demo/web/websocket/golang/net"
	message2 "demo/web/websocket/message"
	"encoding/json"
	"fmt"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	ws "golang.org/x/net/websocket"
)

func GetCurrentPath() string {
	s, _ := os.Executable()
	return s
}

func GolangChatServer() {
	engine := gin.Default()

	engine.GET("/hello", func(context *gin.Context) {
		context.JSON(200, "hello")
	})
	engine.StaticFS("/static", http.Dir("/Users/myselffan/projects-test/go/go-demo/web/websocket/static"))

	http.Handle("/", engine)
	http.Handle("/chat", ws.Handler(chatServer))

	http.ListenAndServe(":8080", nil)
}

var (
	connectionManager = net.NewManager()
)

func chatServer(conn *ws.Conn) {
	var err error
	var reply string
	for {
		//接受消息
		err = ws.Message.Receive(conn, &reply)
		/**
		error发生时，连接出现异常，跳出循环，关闭连接
		当客户端关闭连接，或者连接中断，读取数据时会发生io.EOF
		*/
		if err != nil {
			fmt.Println("read error, error=" + err.Error())

			uid := connectionManager.GetUid(conn)

			if uid != "" {
				connectionManager.DelConn(uid, conn)
				fmt.Println("webasocket disconneted, conn=" + conn.RemoteAddr().String() + ", uid=" + uid)

				sendGroupMessage(uid + "退出了直播间")
			}

			if err = conn.Close(); err != nil {
				fmt.Println("close connection, conn=" + conn.RemoteAddr().String() + ", uid=" + uid)
				panic(err)
			}
			break
		}

		//群发消息
		data := []byte(reply)
		processMessage(data, conn)
	}
}

func processMessage(message []byte, conn *ws.Conn) {
	var chatMessage = message2.ChatMessage{}

	err := json.Unmarshal(message, &chatMessage)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	switch chatMessage.Type {
	case 1:
		connectionManager.AddConn(chatMessage.Uid, conn)
		fmt.Println("connection connected, addr=" + conn.RemoteAddr().String() + ", uid=" + chatMessage.Uid)

		text := chatMessage.Uid + "进入了直播间"
		sendGroupMessage(text)
	case 2:
		text := chatMessage.Uid + "退出了直播间"
		sendGroupMessage(text)

		connectionManager.DelConn(chatMessage.Uid, conn)
		fmt.Println("connection disconnected, addr=" + conn.RemoteAddr().String() + ", uid=" + chatMessage.Uid)
	case 3:
		sendGroupMessage(chatMessage.Uid + ": " + chatMessage.Text)
	}
}

func sendGroupMessage(message string) {
	for conn := range connectionManager.Conns {
		ws.Message.Send(conn, message)
	}
}
